from datetime import datetime, timedelta
from typing import Optional
from jose import JWTError, jwt
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from app.config.settings import settings  # 假设存在配置文件定义白名单
from app.core.encryption_utils import cipher
from app.core.local_logging import setup_logging

logger = setup_logging()



def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    """
    创建访问令牌（JWT）。
    Args:
        data: 包含用户信息的字典。
        expires_delta: 令牌的过期时间。
    Returns:
        str: 加密后的访问令牌。
    """
    to_encode = data.copy()
    if expires_delta:  # 如果提供了过期时间，使用该时间，否则使用默认设置
        expire = datetime.now() + expires_delta
    else:
        expire = datetime.now() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, cipher.private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.PKCS8,
        encryption_algorithm=serialization.NoEncryption()
    ), algorithm=settings.ALGORITHM)
    # 加密生成的 Token
    encrypted_token = cipher.encrypt(encoded_jwt)
    return encrypted_token


def verify_token(token: str):
    """
    验证访问令牌。
    Args:
        token: 加密后的访问令牌。
    Returns:
        dict: 解码后的用户信息。
    """
    try:
        # 解密接收到的 Token
        decrypted_token = cipher.decrypt(token)
        payload = jwt.decode(decrypted_token, cipher.public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo
        ), algorithms=[settings.ALGORITHM])
        logger.debug(f"Token payload: {payload}")
        logger.debug(f"Token expiration: {payload}")  # 打印 exp 字段以确认其存在和格式正确
        return payload
    except JWTError:
        return "Invalid token"